#!/usr/bin/env python
# encoding: utf-8
"""
train_Test.py

Created by Orestis Markou on 2007-12-12.
Copyright (c) 2007 Orestis Markou. All rights reserved.
"""

import unittest
import os
from greeklish.new_hmm import HMM
from greeklish.greeklishout import Trainer
from greeklish import alignment
from greeklish import char_inputs
from testutils import print_sequence as prints

class MockSettings(object):
    """docstring for MockSettings"""
    def __init__(self):
        super(MockSettings, self).__init__()
        self.ALIGN_FUNCTION = alignment.align3
        self.SPLIT_FUNCTION = alignment.split_smart
        self.SIMPLE_WORDS = True
        self.GREEK_PART_LIST = char_inputs.greek_parts
        self.GREEK_SPLIT_LIST = char_inputs.gr_split
        self.GREEKLISH_SPLIT_LIST = char_inputs.greeklish_split
        self.SIMPLE_CHARS_LIST = char_inputs.simple_ch
        self.OPTIMIZE = False
        self.NUMPY = True
        
class TrainerTestCase1(unittest.TestCase):
    def setUp(self):
        self.filename_gr = 'train_gr_Test.file'
        f = open(self.filename_gr, 'wb')
        f.write('ορεστης-645987\n')
        f.write('μαρκου-234\n')
        f.close()
        self.filename_grkl = 'train_grkl_Test.file'
        f = open(self.filename_grkl, 'wb')
        f.write('orestis-ορεστης\n')
        f.write('markou-μαρκου\n')
        f.close()
        self.settings = MockSettings()
    
    def tearDown(self):
        """docstring for tearDown"""
        os.remove(self.filename_gr)
        os.remove(self.filename_grkl)
            
    def testInit(self):
        trainer = Trainer(self.filename_gr, self.filename_grkl, self.settings)
        greek_words = [{'greek':u'ορεστης', 'count':645987.0},{'greek':u'μαρκου','count':234.0}]
        self.assertEqual(trainer.words_greek,greek_words)
        greeklish_words = [{'greeklish':'orestis', 'greek':u'ορεστης'},{'greeklish':'markou','greek':u'μαρκου'}]
        self.assertEqual(trainer.words_greeklish,greeklish_words)
  
    def testProcessObservations(self):
        trainer = Trainer(self.filename_gr, self.filename_grkl, self.settings)
        obs = trainer._process_observations()
        exp = [
        ([('or',u'ορ'),('es',u'εσ'),('ti',u'τη'),('s',u'ς')],1),
        ([('ma',u'μα'),('rk',u'ρκ'),('ou',u'ου')],1)
        ]
        # prints(exp)
        # prints(obs)
        self.assertEqual(obs, exp)

    def testTrainObservations(self):
        trainer = Trainer(self.filename_gr, self.filename_grkl, self.settings)
        #this is needed in order to extract the states/observations
        seq = trainer._process_observations()
        states_, observations = trainer.extract_states_observations(seq)
        trainer.train()

        states = trainer._process_states(states_)
        exp = [
        ([ u'ορ',u'εσ',u'τη',u'ς' ],645987.0),
        ([ u'μα',u'ρκ', u'ου'], 234.0)
        ]
        # prints(states)
        # prints(exp)
        self.assertEqual(states, exp)
        self.assertEqual(set(trainer.hmm.omega_O),set(['or','es','ti','s','ma','rk','ou']))
        
        
    def testProcessStates(self):
        """docstring for testProcessStates"""
        trainer = Trainer(self.filename_gr, self.filename_grkl, self.settings)
        #this is needed in order to extract the states/observations
        # seq = trainer._process_observations()
        # trainer.train_observations(seq)
        # states = trainer._process_states()
        # trainer.train_states(states)
        trainer.train()
        self.assertEqual(set(trainer.hmm.omega_X),set([u'ορ',u'εσ',u'τη',u'ς',u'μα',u'ρκ',u'ου']))
        
        
        

    
class TrainerTestCase2(unittest.TestCase):
    def setUp(self):
        self.filename_gr = 'train_gr_Test.file'
        f = open(self.filename_gr, 'wb')
        f.write('ορεστης-750\n')
        f.write('μαρκου-150\n')
        f.write('μαρκα-100\n')        
        f.close()
        self.filename_grkl = 'train_grkl_Test.file'
        f = open(self.filename_grkl, 'wb')
        f.write('orestis-ορεστης\n')
        f.write('markou-μαρκου\n')
        f.write('marka-μαρκα\n')
        f.close()
        self.settings = MockSettings()
        self.trainer = Trainer(self.filename_gr, self.filename_grkl, self.settings)
        self.trainer.train()
    
    def tearDown(self):
        """docstring for tearDown"""
        os.remove(self.filename_gr)
        os.remove(self.filename_grkl)
    
    def testStates(self):
        self.assertEqual(set(self.trainer.hmm.omega_X),set([u'ορ',u'εσ',u'τη',u'ς',u'μα',u'ρκ',u'ου',u'α']))

    def testObservations(self):
        self.assertEqual(set(self.trainer.hmm.omega_O),set(['or','es','ti','s','ma','rk','ou', 'a']))

    def testViterbi_simple(self):
        sequence = ('or','es','ti','s')
        hmm = self.trainer.hmm
        res = hmm.viterbi(sequence)
        self.assertEqual(res, [u'ορ',u'εσ',u'τη',u'ς',])
        res = hmm.viterbi(('or','es','ti'))
        self.assertEqual(res, [u'ορ',u'εσ',u'τη',])
        
    
    def testViterbi_missing(self):
        """docstring for testViterbi_missing"""
        sequence = ('or','es','ti','a')
        hmm = self.trainer.hmm
        res = hmm.viterbi(sequence)
        self.assertEqual(res, [u'ορ',u'εσ',u'τη',u'α',])

class TrainerTestCaseOptimize(unittest.TestCase):
    """docstring for TrainerTestCaseOptimize"""
    def setUp(self):
        self.filename_gr = 'train_gr_Test.file'
        f = open(self.filename_gr, 'wb')
        f.write('ορεστης-750\n')
        f.write('μαρκου-150\n')
        f.write('μαρκα-100\n')        
        f.close()
        self.filename_grkl = 'train_grkl_Test.file'
        f = open(self.filename_grkl, 'wb')
        f.write('orestis-ορεστης\n')
        f.write('markou-μαρκου\n')
        f.write('marka-μαρκα\n')
        f.close()
        self.settings = MockSettings()
        self.trainer = Trainer(self.filename_gr, self.filename_grkl, self.settings)
        self.trainer.train()
        trans = []
        for idx1,s1 in enumerate(self.trainer.hmm.omega_X):
            trans.append([])
            for idx2, s2 in enumerate(self.trainer.hmm.omega_X):
                trans[idx1].append(0.004)
        
        trans[0][1]=1.0
        trans[1][2]=1.0        
        trans[2][3]=1.0
        
        trans[4][5]=1.0
        trans[5][6]=0.6
        trans[5][7]=0.4
        self.trans = trans
        
        obs = []
        for idx1, s in enumerate(self.trainer.hmm.omega_X):
            obs.append([])
            for idx2, s2 in enumerate(self.trainer.hmm.omega_O):
                obs[idx1].append(0.00004)
        
        obs[0][0]=1.0
        obs[1][1]=1.0        
        obs[2][2]=1.0
        obs[3][3]=1.0
        obs[4][4]=1.0
        obs[5][5]=1.0
        obs[6][6]=1.0
        obs[7][7]=1.0
        self.obs = obs
        
    def tearDown(self):
        """docstring for tearDown"""
        os.remove(self.filename_gr)
        os.remove(self.filename_grkl)
        

class TrainerTestCase4(unittest.TestCase):
    """docstring for TrainerTestCase4"""
    def setUp(self):
        self.filename_gr = 'train_gr_Test.file'
        f = open(self.filename_gr, 'wb')
        f.write('ορεστης-750\n')
        # f.write('της-100\n')
        f.write('μαρκου-150\n')
        f.write('μαρκα-100\n')        
        f.close()
        self.filename_grkl = 'train_grkl_Test.file'
        f = open(self.filename_grkl, 'wb')
        f.write('orestis-ορεστης\n')
        f.write('markou-μαρκου\n')
        f.write('marka-μαρκα\n')
        f.close()
        self.settings = MockSettings()

    
    def tearDown(self):
        """docstring for tearDown"""
        os.remove(self.filename_gr)
        os.remove(self.filename_grkl)
    
    def testUnoptimized(self):
        self.settings.OPTIMIZE = False
        self.trainer = Trainer(self.filename_gr, self.filename_grkl, self.settings)
        self.trainer.train()
        hmm = self.trainer.hmm
        res = hmm.viterbi(('or','es','ti','s'))
        self.assertEqual(res, [u'ορ',u'εσ',u'τη',u'ς',])
        res = hmm.viterbi(('or','es','ti'))
        self.assertEqual(res, [u'ορ',u'εσ',u'τη',])
        res = hmm.viterbi( ('or','es','ti','a'))
        self.assertEqual(res, [u'ορ',u'εσ',u'τη',u'α',])
    
    def testOptimized_without_NUMPY(self):
        self.settings.OPTIMIZE = True
        self.trainer = Trainer(self.filename_gr, self.filename_grkl, self.settings)
        self.trainer.train()
        hmm = self.trainer.hmm
        res = hmm.viterbi(('or','es','ti','s'))
        self.assertEqual(res, [u'ορ',u'εσ',u'τη',u'ς',])
        res = hmm.viterbi(('or','es','ti'))
        self.assertEqual(res, [u'ορ',u'εσ',u'τη',])
        res = hmm.viterbi( ('or','es','ti','a'))
        self.assertEqual(res, [u'ορ',u'εσ',u'τη',u'α',])
    
    def testOptimized_with_NUMPY(self):
        self.settings.OPTIMIZE = True
        self.trainer = Trainer(self.filename_gr, self.filename_grkl, self.settings)
        self.trainer.train()
        hmm = self.trainer.hmm
        res = hmm.viterbi(('or','es','ti','s'))
        self.assertEqual(res, [u'ορ',u'εσ',u'τη',u'ς',])
        res = hmm.viterbi(('or','es','ti'))
        self.assertEqual(res, [u'ορ',u'εσ',u'τη',])
        res = hmm.viterbi( ('or','es','ti','a'))
        self.assertEqual(res, [u'ορ',u'εσ',u'τη',u'α',])    
        

class TrainerTestCase5(unittest.TestCase):
    """docstring for TrainerTestCase4"""
    def setUp(self):
        self.filename_gr = 'train_gr_Test5.file'
        f = open(self.filename_gr, 'wb')
        f.write('και-750\n')
        f.write('της-100\n')
        f.write('μαρκου-250\n')
        f.write('μαρκες-150\n')
        f.write('μαρκα-100\n')        
        f.write('ασχετο-250\n')
        f.write('ξεκαρφωτο-150\n')
        f.write('βλακεια-100\n')

        f.close()
        self.filename_grkl = 'train_grkl_Test5.file'
        f = open(self.filename_grkl, 'wb')
        f.write('orestis-ορεστης\n')
        f.write('σπουργιτι-spoyrgiti\n')
        f.write('δεντρο-dentro\n')
        f.write('σαμιακι-samiaki\n')
        f.write('κρεβατι-krevati\n')
        f.write('τραπεζι-trapezi\n')
        f.write('ou-ου\n')
        f.write('asxeto-ασχετο\n')
        f.write('ksekarfoto-ξεκαρφωτο\n')
        f.write('vlakeia-βλακεια\n')
        f.write('markou-μαρκου\n')
        f.write('marka-μαρκα\n')
        f.write('markes-μαρκες\n')
        f.write('kai-και\n')
        
        f.close()
        self.settings = MockSettings()
        
    def tearDown(self):
        """docstring for tearDown"""
        os.remove(self.filename_gr)
        os.remove(self.filename_grkl)
  
    def testOptimized_with_NUMPY_5(self):
        self.settings.OPTIMIZE = True
        self.trainer = Trainer(self.filename_gr, self.filename_grkl, self.settings)
        self.trainer.train()
        hmm = self.trainer.hmm
        # print hmm._opt_state_trans
        # print hmm._opt_obs_prob
        res = hmm.viterbi(('ma','rk','a'))
        self.assertEqual(res, [u'μα',u'ρκ',u'α',])
        res = hmm.viterbi(('ma','rk','ou'))
        self.assertEqual(res, [u'μα',u'ρκ',u'ου',])
        res = hmm.viterbi( ('ma','rk','es',))
        self.assertEqual(res, [u'μα',u'ρκ',u'ες',])       
        
        
if __name__ == '__main__':
    unittest.main()

